package com.tfswx.jkgl.core.utils;

import cn.hutool.core.convert.Convert;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tfswx.jkgl.core.exception.AppException;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @author ricky
 * @date 2021/12/24
 */
public class ServiceUtil {

    private static final Map<String, Object> serviceMap = new HashMap<>();

    private ServiceUtil() {
    }

    private static Object getService(String serviceName) {
        return serviceMap.computeIfAbsent(serviceName, k -> {
            try {
                return SpringUtil.getBean(serviceName);
            } catch (Exception e) {
                return null;
            }
        });
    }

    public static Object excuteMethod(String serviceName, String methodName, Object inputDTO) {
        Object service = getService(serviceName);
        if (service == null) {
            throw new RuntimeException("没有找到【" + serviceName + "】服务");
        }
        Class<?> aClass = service.getClass();
        for (Method method : aClass.getMethods()) {
            String name = method.getName();
            if (!name.equals(methodName)) {
                continue;
            }
            Class<?>[] parameterTypes = method.getParameterTypes();
            try {
                Object invoke;
                if (parameterTypes.length > 0) {
                    Object o = Convert.convert(method.getGenericParameterTypes()[0], inputDTO);
                    invoke = method.invoke(service, o);
                } else {
                    invoke = method.invoke(service);
                }
                Object o = JSON.toJSON(invoke);
                if (o instanceof JSONArray) {
                    return ((JSONArray) o).toJavaList(Object.class);
                } else if (o instanceof JSONObject) {
                    return ((JSONObject) o).toJavaObject(Map.class);
                }
                return invoke;

            } catch (IllegalAccessException e) {
                throw new AppException(e);
            } catch (InvocationTargetException e) {
                Throwable targetException = e.getTargetException();
                if (targetException instanceof RuntimeException) {
                    throw (RuntimeException) targetException;
                }
                AppException appException = new AppException(targetException.getMessage(), targetException.getCause());
                appException.setStackTrace(targetException.getStackTrace());
                throw appException;
            }
        }
        throw new RuntimeException("没有找到方法【" + serviceName + "." + methodName + "】");
    }
}
